home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
tiff
/
packbits.c
< prev
next >
Wrap
Text File
|
1987-01-16
|
4KB
|
207 lines
#define MAXINBYTES 127
#define INITIAL 0
#define LITERAL 1
#define UNDECIDED 2
char CalcRaw ARGS((WORD, LPSTR, char *));
LOCAL char CalcRaw (n, lpIn, rawrunbuf)
WORD n;
LPSTR lpIn;
char *rawrunbuf;
{
char ncounts = 0;
char thisbyte;
char cnt = 1;
char runbyte = *lpIn++;
while (--n) {
thisbyte = *lpIn++;
if (thisbyte == runbyte) {
cnt++;
} else { /* write prev raw run, & start a new one */
*rawrunbuf++ = cnt;
ncounts++;
cnt = 1;
runbyte = thisbyte;
}
}
*rawrunbuf = cnt;
return (++ncounts);
}
/* this should be a Mac ToolBox lookalike
* n must be <= 127
*/
void PackBits ARGS((LPSTR *, LPSTR *, WORD));
LOCAL void PackBits (plpIn, plpOut, n)
LPSTR *plpIn;
LPSTR *plpOut;
WORD n;
{
LPSTR lpIn = *plpIn;
LPSTR lpOut = *plpOut;
char runcount;
char rawrunbuf[MAXINBYTES];
char *pRaw;
char nraw;
char state;
char rawcount;
char twins;
RC err = SUCCESS;
if (n <= 0 || n > 127) {
DBMSG(("PackBits: n=%u\n", n));
err = IE_BUG;
goto cu0;
}
/* calculate raw run counts
*/
nraw = CalcRaw (n, lpIn, rawrunbuf);
if (nraw <= 0 || nraw > 127) {
DBMSG(("PackBits: nraw=%u\n",nraw));
err = IE_BUG;
goto cu0;
}
/* initialize a few things
*/
pRaw = rawrunbuf;
state = INITIAL;
/* go through the raw run count array
*/
while (nraw--) {
rawcount = *pRaw++;
if (rawcount < 1 || rawcount > 127) {
DBMSG(("PackBits: rawcount=%d\n",rawcount));
err = IE_BUG;
goto cu0;
}
if (state == INITIAL) {
if (rawcount == 1) {
state = LITERAL;
runcount = 1;
} else if (rawcount == 2) {
state = UNDECIDED;
runcount = 2;
} else { /* rawcount >= 3 */
/* state = INITIAL; */
/* write replicate run and update ptrs
*/
*lpOut++ = -(rawcount - 1);
*lpOut++ = *lpIn;
lpIn += rawcount;
}
} else if (state == LITERAL) {
if (rawcount < 3) {
runcount += rawcount;
} else {
state = INITIAL;
/* write literal run and update ptrs
*/
*lpOut++ = runcount - 1;
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
lmemcpy (lpOut, lpIn, runcount);
lpOut += runcount;
lpIn += runcount;
/* write replicate run and update ptrs
*/
*lpOut++ = -(rawcount - 1);
*lpOut++ = *lpIn;
lpIn += rawcount;
}
} else { /* state = UNDECIDED */
if (rawcount == 1) {
state = LITERAL;
runcount++;
} else if (rawcount == 2) {
/* state = UNDECIDED */
runcount += 2;
} else { /* rawcount >= 3 */
state = INITIAL;
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
/* write out runcount/2 twin replicate runs */
for (twins = (runcount>>1); twins--; ) {
*lpOut++ = -1;
*lpOut++ = *lpIn;
lpIn += 2;
}
/* write out this replicate run
*/
*lpOut++ = -(rawcount - 1);
*lpOut++ = *lpIn;
lpIn += rawcount;
}
} /* end of UNDECIDED case */
} /* end of main for loop */
/* clean up hanging states
*/
if (state == LITERAL) {
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
/* write out literal run
*/
*lpOut++ = runcount - 1;
lmemcpy (lpOut, lpIn, runcount);
lpOut += runcount;
lpIn += runcount;
}
else if (state == UNDECIDED) {
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
/* write out runcount/2 twin replicate runs
*/
for (twins = (runcount>>1); twins--; ) {
*lpOut++ = -1;
*lpOut++ = *lpIn;
lpIn += 2;
}
}
/* set up return values
*/
*plpIn = lpIn;
*plpOut = lpOut;
cu0: return;
} /* that's all, folks */
#endif /* ifndef MACINTOSH */
/* if you might have more than 127 input bytes, call this routine instead
* of the basic PackBits
*/
void BigPackBits ARGS((LPSTR *, LPSTR *, WORD));
LOCAL void BigPackBits (plpIn, plpOut, n)
LPSTR *plpIn;
LPSTR *plpOut;
WORD n;
{
WORD topack;
while (n) {
topack = (n < MAXINBYTES) ? n : MAXINBYTES;
PackBits (plpIn, plpOut, topack);
n -= topack;
}
}